/**
 * Copyright 2014 wasu.com
 *
 *
 * Create on 2015-5-17 下午12:48:44
 */
package xiaojian.toolkit.handler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import xiaojian.toolkit.base.SendbackResponseHelper;

import com.google.common.base.Preconditions;

/**
 * @author <a href="mailto:caoxiaojian@wasu.com>xiaojian.cao</a>
 * 
 */
public abstract class AbstractHttpReqHandler<Q extends AbstractRequest, R extends AbstractResponse>
		extends AbstractReqHandler<AbstractRequest> {

	private static final Logger logger = LoggerFactory
			.getLogger(AbstractHttpReqHandler.class);

	@Autowired
	protected SendbackResponseHelper sendbackResponseHelper = null;

	/**
	 * @return the sendbackResponseHelper
	 */
	public SendbackResponseHelper getSendbackResponseHelper() {
		return sendbackResponseHelper;
	}

	/**
	 * @param sendbackResponseHelper
	 *            the sendbackResponseHelper to set
	 */
	public void setSendbackResponseHelper(
			SendbackResponseHelper sendbackResponseHelper) {
		this.sendbackResponseHelper = sendbackResponseHelper;
	}

	/**
	 * 要求子类生成一个回应对象。
	 * 
	 * @param request
	 * @return
	 */
	protected abstract R newResponse(Q request);

	/**
	 * @see com.wasu.upm.commons.handler.ReqHandler#doReq(com.wasu.upm.commons.AbstractUPMRequest)
	 */
	protected abstract void doReq1(Q request, R response);
	
	/**
	 * 让子类去处理处理过程中异常。
	 * 
	 * @param exception
	 */
	protected abstract void processException(Exception exception,
			Q request, R response);

	/**
	 * @see com.wasu.upm.commons.handler.ReqHander#doReq(com.wasu.upm.commons.
	 *      AbstractUPMRequest)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void doReq0(AbstractRequest request) {
		Preconditions.checkArgument(request != null
				&& request.getIdentification() != null);

		logger.debug("Start process request[{}].", request);

		AbstractResponse response = newResponse((Q) request);

		if (response == null) {
			logger.error("Pls implement method[newResponse(AbstractUPMRequest request)], request["
					+ request + "].");
			return;
		}
		
		try {
			doReq1((Q) request, (R) response);
		} catch (Exception exception) {
			logger.error("Prorcess reqest[" + request + "] fail.", exception);
			processException(exception, (Q) request, (R) response);

		}

		send(request, response);

	}
	
	protected void send(AbstractRequest request, AbstractResponse response) {
		response.setIdentification(request.getIdentification());
		sendbackResponseHelper.makeAndSendback(response, request);
	}

}
